/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package phd.dupenois.changeidentifiers.algorithms.chihull;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.TreeSet;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import phd.dupenois.changeidentifiers.dotpatterns.DotPattern;
import phd.dupenois.changeidentifiers.dotpatterns.DotPatternNotFinalised;
import phd.dupenois.changeidentifiers.footprints.Footprint;
import phd.dupenois.changeidentifiers.footprints.algorithms.FootprintAlgorithm;
import uk.co.dupenois.geometry.Coordinate;
import uk.co.dupenois.geometry.CoordinateList;
import uk.co.dupenois.geometry.Line;
import uk.co.dupenois.geometry.combinatorialmap.CombinatorialMap;
import uk.co.dupenois.geometry.combinatorialmap.CombinatorialMapException;

/**
 *
 * @author Max
 */
public class ChiHull extends FootprintAlgorithm{

    private double lengthParameter;

    public void initialise() {
        this.lengthParameter = 100;
    }



    public Footprint generateFootprint(DotPattern pattern) throws Exception {
//        System.out.println("\n------------");
//        long startTime = System.currentTimeMillis();
        Footprint footprint = new Footprint();

        if(!pattern.isFinalised()) pattern.finalise();
        CoordinateList coordinateList = null;
        try {
            coordinateList = pattern.getList();
        } catch (DotPatternNotFinalised ex) {
            //Won't happen, check for this in line above
        }
        DelaunayTriangulation triangulation = constructDelaunayTriangulation(coordinateList.getByX());
//        System.out.println("Total Triangulation Took: "+(System.currentTimeMillis()-startTime)+" ms");
//        startTime = System.currentTimeMillis();
        CombinatorialMap combinatorialMap = constructChiHull(triangulation);
//        System.out.println("CombinatorialMap Took: "+(System.currentTimeMillis()-startTime)+" ms");
//        startTime = System.currentTimeMillis();
        Coordinate[] coords = combinatorialMap.getOrderedBoundaryVertices();
//        System.out.println("Ordering Took: "+(System.currentTimeMillis()-startTime)+" ms");
//        startTime = System.currentTimeMillis();
        Coordinate start = null;
        Coordinate first = null;
        Coordinate finish = null;
        for(Coordinate c: coords){
            if(start==null){
                start = c;
                first = c;
                continue;
            }
            finish = c;
            footprint.addLine(start, finish);
            start = finish;
        }
        footprint.addLine(finish, first);
//        System.out.println("Footprint creation: "+(System.currentTimeMillis()-startTime)+" ms");
        return footprint;
    }

    public CombinatorialMap constructChiHull(DelaunayTriangulation triangulation){
        ChiHullEngine engine = new ChiHullEngine(lengthParameter, triangulation.getEdgesLeftToRight());
        try {
            return engine.generateChiHull();
        } catch (CombinatorialMapException ex) {
            ex.printStackTrace();
            return null;
        }
    }


    public DelaunayTriangulation constructDelaunayTriangulation(TreeSet<Coordinate> list){
        ArrayList<Coordinate> arrayList = new ArrayList<Coordinate>();
        arrayList.addAll(list);
//        long startTime = System.currentTimeMillis();
        DivideAndConquerDelaunayTriangulationEngine.DRAW_ONLY_FINISHED = true;
        DivideAndConquerDelaunayTriangulationEngine.PAUSE = 0;
        DivideAndConquerDelaunayTriangulationEngine.coordinateOfInterest = null;
        DivideAndConquerDelaunayTriangulationEngine engine =
                new DivideAndConquerDelaunayTriangulationEngine(arrayList, true);
//        System.out.println("[DT] Constructor Took: "+(System.currentTimeMillis()-startTime)+" ms");
        return engine.triangulate();
    }



}
